package xin.yangshuai.springsecurity03.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.*;
import org.springframework.security.provisioning.UserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import xin.yangshuai.springsecurity03.textmessage.TextMessageAuthenticationFilter;
import xin.yangshuai.springsecurity03.textmessage.TextMessageAuthenticationProvider;

@Configuration
// @EnableWebSecurity
@EnableMethodSecurity //开启基于方法的授权
public class WebSecurityConfig {

//    @Bean
//    public UserDetailsService userDetailsService() {
//        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
//        // 此时配置文件中的用户名和密码将不可用
//        manager.createUser(User.withDefaultPasswordEncoder().username("user").password("password").authorities("USER_LIST").build());
//        return manager;
//    }

//    @Autowired
//    private DataSource dataSource;

//    @Bean
//    public UserDetailsManager userDetailsManager() {
//
//        JdbcUserDetailsManager manager = new JdbcUserDetailsManager();
//        manager.setDataSource(dataSource);
//
//        if (!manager.userExists("user")) {
//            manager.createUser(User.withDefaultPasswordEncoder().username("user").password("password").authorities("USER_LIST").build());
//        }
//
//        return manager;
//    }

    @Autowired
    private TextMessageLoginConfigurer textMessageLoginConfigurer;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        // 开启授权保护
        http.authorizeRequests(new Customizer<ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry>() {
            @Override
            public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry expressionInterceptUrlRegistry) {

                // 具有USER_LIST权限的用户可以访问/user/list
                // expressionInterceptUrlRegistry.requestMatchers("/user/list").hasAuthority("USER_LIST");

                expressionInterceptUrlRegistry
                        .requestMatchers("/user/add").permitAll()
                        .requestMatchers("/sms-login").permitAll()
                        // 对所有请求开启授权保护
                        .anyRequest()
                        // 已经认证的请求会被自动授权
                        .authenticated();
            }
        });

        // 自定义登录页面
        http.formLogin(new Customizer<FormLoginConfigurer<HttpSecurity>>() {
            @Override
            public void customize(FormLoginConfigurer<HttpSecurity> httpSecurityFormLoginConfigurer) {
                // 自定义登录页，并且设置无需授权允许访问
                httpSecurityFormLoginConfigurer.loginPage("/login").permitAll();
                // 配置自定义表单的用户名参数，默认值：username
                httpSecurityFormLoginConfigurer.usernameParameter("myusername");
                // 配置自定义表单的密码参数，默认值：password
                httpSecurityFormLoginConfigurer.passwordParameter("mypassword");
                // 校验失败时跳转的地址，默认值：/login?error
                httpSecurityFormLoginConfigurer.failureUrl("/login?error");
            }
        });

        // 自定义登出页面
        http.logout(new Customizer<LogoutConfigurer<HttpSecurity>>() {
            @Override
            public void customize(LogoutConfigurer<HttpSecurity> httpSecurityLogoutConfigurer) {
                // 自定义登出页
                httpSecurityLogoutConfigurer.logoutUrl("/logout");
                // 自定义登出成功后跳转的页面
                httpSecurityLogoutConfigurer.logoutSuccessUrl("/");
            }
        });

        // 自定义拒绝访问页面
        http.exceptionHandling(new Customizer<ExceptionHandlingConfigurer<HttpSecurity>>() {
            @Override
            public void customize(ExceptionHandlingConfigurer<HttpSecurity> httpSecurityExceptionHandlingConfigurer) {
                httpSecurityExceptionHandlingConfigurer.accessDeniedPage("/accessDenied");
            }
        });

        // 关闭csrf攻击防御
        http.csrf(new Customizer<CsrfConfigurer<HttpSecurity>>() {
            @Override
            public void customize(CsrfConfigurer<HttpSecurity> httpSecurityCsrfConfigurer) {
                httpSecurityCsrfConfigurer.disable();
            }
        });

        http.apply(textMessageLoginConfigurer);

        return http.build();
    }
}
